﻿//===============================================================================
// Apolineo Patterns & Practices LeanEngine Framework
//===============================================================================
// Copyright © Apolineo Desenvolvimento de Sistemas Ltda.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq.Mapping;

using LeanEngine.Entity;
using LeanEngine.Validation;
using LeanEngine.Collections;

using LeanEngine.SalesConcept.Business;

namespace LeanEngine.SalesConcept.Entity
{
    //O atributo Table do namespace System.Data.Linq.Mapping é responsável
    //por informar ao lob que a classe se refere a tabela
    //'Sale' no banco de dados

    //Herdamos da interface IDataTransferObject para o ambiente do lob
    //funcione de acordo, porém, não queremos que gerencie as mudanças
    //nos valores das propriedades, faça atualizações pessimistas e envie
    //no comando update somente os dados alterados, além do, versionamento
    //do dado automaticamente
    [Table(Name = "Sale")]
    public class Sale : PlainEntity
    {
        #region Constructor Members

        public Sale()
        {
            this.Customer = new Customer();
            this.Salesman = new Salesman();

            //Inicializa a coleção de itens da venda que utiliza a coleção ChangeTrackerCollection
            //que faz todo o controle das alterações nos itens da coleção
            this.SaleDetailsList = new ChangeTrackerCollection<SaleDetail>();
        }

        #endregion

        #region Sale Members

        //Aqui mapeamos a coluna SalesmanId (seu valor será obtido através da propriedade
        //da classe Salesman que possui o atributo Column como PK) e adicionamos um validador
        //padrão para assegurar que a propriedade tenha uma instancia válida e sua propriedade
        //pk preenchida, e em caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SelectSalesmanRequired'
        [IsNotNullAndHasPrimaryKeysFilled(typeof(ErrorMessages), "SelectSalesmanRequired")]
        [Column(Name = "SalesmanId")]
        public Salesman Salesman
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna SalesmanId (seu valor será obtido através da propriedade
        //da classe Salesman que possui o atributo Column como PK) e adicionamos um validador
        //padrão para assegurar que a propriedade tenha uma instancia válida e sua propriedade
        //pk preenchida, e em caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SelectSalesmanRequired'
        [IsNotNullAndHasPrimaryKeysFilled(typeof(ErrorMessages), "SelectCustomerRequired")]
        [Column(Name = "CustomerId")]
        public Customer Customer
        {
            get;
            set;
        }

        //Coleção de itens da venda que utiliza a coleção ChangeTrackerCollection
        //que faz todo o controle das alterações nos itens da coleção
        [IsNotEmptyList(typeof(ErrorMessages), "SaleDetailRequired")]
        public ChangeTrackerCollection<SaleDetail> SaleDetailsList
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna 'SaleDate' e adicionamos uma validação padrão
        //para assegurar que a data da venda seja preenchida, e em
        //caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SaleDateInvalid'
        [IsNotDefaultDate(typeof(ErrorMessages), "SaleDateInvalid"), 
        Column(Name = "SaleDate")]
        public DateTime SaleDate
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna 'SaleTotal' e adicionamos uma validação padrão
        //para assegurar que o total da venda seja maior que 0, e em
        //caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SaleTotalInvalid'
        [IsGreaterThan(0, typeof(ErrorMessages), "SaleTotalInvalid"),
        Column(Name = "SaleTotal")]
        public decimal SaleTotal
        {
            get;
            set;
        }

        #endregion

        #region ITransferObject Members

        //Aqui mapeamos a coluna PK da tabela Sale e informamos ao lob
        //que o valor dela é gerado pelo banco de dados
        [Column(Name = "SaleId", IsPrimaryKey = true, IsDbGenerated = true)]
        public long Id
        {
            get;
            set;
        }

        #endregion
    }
}
